package com.sxt.generate.generate;

import com.sxt.generate.configuration.Configuration;
import com.sxt.generate.table.Table;
import com.sxt.generate.util.MyDateTool;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Properties;

/**
 *
 * @ClassName: Configuration
 * @Description:Configuration
 * @version:v1.0.0
 * @author: haning
 * @date:
 */
public class ExcuteFile {
    private final String  USER_DIR = System.getProperty("user.dir")  + "/..";

    /** eclipse **/
    //private final String  USER_DIR = System.getProperty("user.dir") + "/..";

    /** idea **/
    // private final String  USER_DIR = System.getProperty("user.dir");

    private Table table;
    private String  basePackage = "com.sxt";
    private String  entityPackage;
    private String  mapperPackage;
    private String  daoPackage;
    private String  servicePackage;
    private String  serviceImplPackage;
    private String  controllerPackage;

    private String  entityTemplate = "${className}";
    private String  mapperTemplate = "${className}Dao";
    private String  daoTemplate = "${className}Dao";
    private String  serviceTemplate = "${className}Service";
    private String  serviceImplTemplate = "${className}ServiceImpl";
    private String  controllerTemplate =  "${className}Controller";


   public ExcuteFile(Table table) {
       this.table = table;
   }


    public void  generateFile(Table table) {
        if(Configuration.getTemplate().containsKey("basePackage")) {
            this.setBasePackage( Configuration.getTemplate().get("basePackage") );
            this.entityPackage = this.getBasePackage() + ".entity";
            this.mapperPackage = this.getBasePackage() + ".dao";
            this.daoPackage = this.getBasePackage() + ".dao";
            this.servicePackage = this.getBasePackage() + ".service";
            this.serviceImplPackage = this.getBasePackage() +".service.impl";
            this.controllerPackage = this.getBasePackage() +".web";
        }
        System.out.println("\n********************* ");
        System.out.println("[开始生成:" + table.getClassName()+ "]");
        this.generateEntityClass(table);
        this.generateMapperClass(table);
        //this.generateDaoClass(table);
        this.generateMapperXML(table);
        this.generateServiceClass(table);
        this.generateServiceIClass(table);
        this.generateControllerClass(table);
        System.out.println("[结束生成] 生成模版文件完成");

    }

    public void  generateEntityClass(Table table)  {
        table.getClazz().setActionType("entity");
        final String fileType = "java";
        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), entityTemplate + "." + fileType},"/") ;
        String entityModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getSource().get("entity.module"))){
            entityModule = Configuration.getSource().get("entity.module");
        }
        
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  entityModule,
                        table.getClazz().getSourceDir(),
                        StringUtils.lowerCase(entityPackage).replaceAll("\\.","/"),
                        table.getClazz().getClassName() + "." + fileType},"/");
        this.excuteVelocity(table, temp, output);


    }

    public void  generateMapperXML(Table table ) {

        table.getClazz().setActionType("xml");
        String fileType = "xml";

        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), mapperTemplate + "." + fileType},"/") ;
        String mapperModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getResource().get("mapper.module"))){
           // mapperModule = Configuration.getResource().get("mapper.module");
            mapperModule = Configuration.getSource().get("mapper.module");
        }
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  mapperModule,
                table.getClazz().getSourceDir(),
               // "mybatis/mapper/mysql",
                StringUtils.lowerCase(mapperPackage).replaceAll("\\.","/"),
                table.getClazz().getClassName() + "Dao." + fileType},"/");
        this.excuteVelocity(table, temp, output);
    }


    public void  generateMapperClass(Table table) {
        table.getClazz().setActionType("mapper");
        final String fileType = "java";
        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), mapperTemplate + "." + fileType},"/") ;
        String mapperModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getSource().get("mapper.module"))){
            mapperModule = Configuration.getSource().get("mapper.module");
        }
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  mapperModule,
                table.getClazz().getSourceDir(),
                StringUtils.lowerCase(mapperPackage).replaceAll("\\.","/"),
                table.getClazz().getClassName() + "Dao." + fileType},"/");
        this.excuteVelocity(table, temp, output);
    }


    public void generateDaoClass(Table table){
        table.getClazz().setActionType("dao");
        final String fileType = "java";

        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), daoTemplate + "." + fileType},"/") ;
        String daoModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getSource().get("dao.module"))){
            daoModule = Configuration.getSource().get("dao.module");
        }
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  daoModule,
                table.getClazz().getSourceDir(),
                StringUtils.lowerCase(daoPackage).replaceAll("\\.","/"),
                table.getClazz().getClassName() + "Dao." + fileType},"/");
        this.excuteVelocity(table, temp, output);
    }

    public void generateServiceClass(Table table)  {

        table.getClazz().setActionType("service");
        final String fileType = "java";

        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), serviceTemplate + "." + fileType},"/") ;
        String serviceModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getSource().get("service.module"))){
            serviceModule = Configuration.getSource().get("service.module");
        }
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  serviceModule,
                table.getClazz().getSourceDir(),
                StringUtils.lowerCase(servicePackage).replaceAll("\\.","/"),
                table.getClazz().getClassName() + "Service." + fileType},"/");
        this.excuteVelocity(table, temp, output);
    }

    public void  generateServiceIClass(Table table) {

        table.getClazz().setActionType("service");
        final String fileType = "java";

        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), serviceImplTemplate + "." + fileType},"/") ;
        String serviceModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getSource().get("service.module"))){
            serviceModule = Configuration.getSource().get("service.module");
        }
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  serviceModule,
                table.getClazz().getSourceDir(),
                StringUtils.lowerCase(serviceImplPackage).replaceAll("\\.","/"),
                table.getClazz().getClassName() + "ServiceImpl." + fileType},"/");
        this.excuteVelocity(table, temp, output);
    }


    public void  generateControllerClass(Table table)  {

        table.getClazz().setActionType("controller");
        final String fileType = "java";

        String temp = StringUtils.join(new String[]{table.getClazz().getTemplateDir(), controllerTemplate + "." + fileType},"/") ;
        String controllerModule = ".";
        if(StringUtils.isNoneBlank(Configuration.getSource().get("web.module"))){
            controllerModule = Configuration.getSource().get("web.module");
        }
        String path = getOutPath(USER_DIR);
        String output = StringUtils.join(new String[]{path,  controllerModule,
                table.getClazz().getSourceDir(),
                StringUtils.lowerCase(controllerPackage).replaceAll("\\.","/"),
                table.getClazz().getClassName() + "Controller." + fileType},"/");
        this.excuteVelocity(table, temp, output);
    }
    /**
     * 获取是否配置绝对路径
     */
    public String getOutPath(String path){
    	if(StringUtils.isNotEmpty(Configuration.getTemplate().get("project.path"))){
    		return Configuration.getTemplate().get("project.path").trim();
    	}
    	return path;
    }
    
    public void  excuteVelocity( Table table,  String temp, String output) {
        try {

            File outfile = new File(output);
            if(outfile.exists()) {
                System.out.println("   [跳过] 类文件已经存在:" + output);
                return;
            }
            File dir = outfile.getParentFile();
            if (!dir.exists()) dir.mkdirs();

            //val prop = new Properties()
            Properties prop = new Properties();
            prop.load(this.getClass().getResourceAsStream("/velocity.properties"));
            String generateModule = ".";
            if (Configuration.getTemplate().containsKey("generate.module")){
                generateModule = Configuration.getTemplate().get("generate.module");
            }
            
            //加载配置文件
        	prop.put("file.resource.loader.path", USER_DIR + "/" + generateModule + "/" + table.getClazz().getResourceDir());

           // String os = System.getProperties().getProperty("os.name");
            //if(os.startsWith("win") || os.startsWith("Win") ) {}
            //prop.put("runtime.log", "velocity.log")
            Velocity.init(prop);
            System.out.println("   [生成文件] 生成类文件:" + output);
            VelocityContext context = new VelocityContext();
            context.put("table", table);
            context.put("beanName", table.getClazz().getClassName().substring(0, 1).toLowerCase() + table.getClazz().getClassName().substring(1));
            context.put("StringUtils",  new StringUtils());
            context.put("MyDateTool",  new MyDateTool());
            context.put("basePackage", basePackage);
            context.put("entityPackage", entityPackage);
            context.put("mapperPackage", mapperPackage);
            context.put("daoPackage", daoPackage);
            context.put("servicePackage", servicePackage);
            context.put("servicePackage", servicePackage);
            context.put("serviceImplPackage", serviceImplPackage);
            context.put("controllerPackage", controllerPackage);

            Template template = Velocity.getTemplate(temp);


            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile)));
            template.merge(context, writer);
            writer.flush();
            writer.close();


        } catch  (Exception e){

            e.printStackTrace();
        }

    }

    public Table getTable() {
        return table;
    }

    public void setTable(Table table) {
        this.table = table;
    }

    public String getBasePackage() {
        return basePackage;
    }

    public void setBasePackage(String basePackage) {
        this.basePackage = basePackage;
    }

    public String getEntityPackage() {
        return entityPackage;
    }

    public void setEntityPackage(String entityPackage) {
        this.entityPackage = entityPackage;
    }

    public String getMapperPackage() {
        return mapperPackage;
    }

    public void setMapperPackage(String mapperPackage) {
        this.mapperPackage = mapperPackage;
    }

    public String getDaoPackage() {
        return daoPackage;
    }

    public void setDaoPackage(String daoPackage) {
        this.daoPackage = daoPackage;
    }

    public String getServicePackage() {
        return servicePackage;
    }

    public void setServicePackage(String servicePackage) {
        this.servicePackage = servicePackage;
    }

    public String getServiceImplPackage() {
        return serviceImplPackage;
    }

    public void setServiceImplPackage(String serviceImplPackage) {
        this.serviceImplPackage = serviceImplPackage;
    }

    public String getControllerPackage() {
        return controllerPackage;
    }

    public void setControllerPackage(String controllerPackage) {
        this.controllerPackage = controllerPackage;
    }


}
